package com.liwenfeng;

import com.liwenfeng.domain.Account;

import java.lang.invoke.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;

public class LambdaMethodReferenceTest {
    public static void main(String[] args) throws Throwable {

/*
        //1.方法引用创建函数对象
//        Function<Account,String> fun = Account::getName;
        //等同于
        //2.实现类方法创建函数对象
        Function<Account,String> fun = new MyMethodReference();
        System.out.println(fun.apply(new Account(2, "张三", 55.0)));
*/

        //方法引用实现原理：
        //3.LambdaMetafactory工厂法创建函数对象
        MethodHandles.Lookup lookup = MethodHandles.lookup();
        MethodHandle impl = lookup.findVirtual(Account.class, "getName", MethodType.methodType(String.class));
        CallSite cs = LambdaMetafactory.metafactory(
                lookup,
                "apply",
                MethodType.methodType(Function.class),
                MethodType.methodType(Object.class, Object.class),
                impl,
                MethodType.methodType(String.class, Account.class)
        );
        Function<Account,String> fun = (Function< Account,String>) cs.getTarget().invoke();

        System.out.println(fun.apply(new Account(2, "张三", 55.0)));
    }

    static final class MyMethodReference implements Function<Account,String>{
        @Override
        public String apply(Account account) {
            return account.getName();
        }
    }

    public int add(BinaryOperator<Integer> op){
        return op.apply(4,5);
    }
}
